package com.minit.connector.http;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class HttpProcessor implements Runnable {

    Socket socket;

    boolean available = false;

    HttpConnector connector;

    private int serverPort = 0;

    private boolean keepAlive = false;

    private boolean http11 = true;

    public HttpProcessor(HttpConnector connector) {
        this.connector = connector;
    }

    @Override
    public void run() {
        while (true) {
            // wait for next socket to be assigned
            Socket socket = await();
            if (socket == null) continue;

            process(socket);

            connector.recycle(this);
        }
    }

    public void start() {
        Thread thread = new Thread(this);
        thread.start();
    }

    public void process(Socket socket) {
//        try {
//            Thread.sleep(3000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        InputStream input = null;
        OutputStream output = null;

        try {
            input = socket.getInputStream();
            output = socket.getOutputStream();

            keepAlive = true;

            while (keepAlive) {

                HttpRequestImpl request = new HttpRequestImpl(input);
                request.parse(socket);

                // handle session
                if (request.getSessionId() == null || request.getSessionId().equals("")) {
                    request.getSession(true);
                }

//            Request request = new Request(input);
//            request.parse();

                HttpResponseImpl response = new HttpResponseImpl(output);
                response.setRequest(request);

                // request set response
                request.setResponse(response);

                response.sendHeaders();

                if (request.getUri().startsWith("/servlet/")) {
                    ServletProcessor processor = new ServletProcessor(this.connector);
                    processor.process(request, response);
                } else {
                    StaticResourceProcessor processor = new StaticResourceProcessor();
                    processor.process(request, response);
                }

                finishResponse(response);
                System.out.println("response header connection ---- " + response.getHeader("Connection"));
                if ("close".equals(response.getHeader("Connection"))) {
                    keepAlive = false;
                }
            }
            // close the socket
            socket.close();
            socket = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void finishResponse(HttpResponseImpl response) {
        response.finishResponse();
    }

    synchronized void assign(Socket socket) {
        while (available) {
            try {
                wait();
            } catch (InterruptedException e) {

            }
        }
        this.socket = socket;
        available = true;
        notifyAll();
    }

    private synchronized Socket await() {
        while (!available) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
        Socket socket = this.socket;
        available = false;
        notifyAll();
        return socket;
    }
}
